#include "twebsocketclient.h"
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QTextEdit>
#include <QDateTime>
#include <QFileDialog>
TWebSocketClient::TWebSocketClient(QWidget *parent)
    : QMainWindow(parent)
    , m_pUrlLabel(new QLabel(this))
    , m_pUrlLineEdit(new QLineEdit(this))
    , m_pStartButton(new QPushButton(this))
    , m_pCloseButton(new QPushButton(this))
    , m_pTextEdit(new QTextEdit(this))
    , m_pSendButton(new QPushButton(this))
    , m_pDisplayTextEdit(new QTextEdit(this))
    , m_pSelectImgButton(new QPushButton(this))
    , m_pSendImgButton(new QPushButton(this))
    //, timer(new QTimer(this))
{
    resize(500, 500);
    initUI();
    initConnect();
}

void TWebSocketClient::initConnect()
{
    connect(m_pSendButton, &QPushButton::released, [this]() {
        if (client == nullptr || !client->isConnected()) {
            m_pDisplayTextEdit->append("Please open first!");
            std::cout << "客户端无连接" << std::endl;
        }
        else
        {
                Json::Value root;
                root["cmd"] = cmdToInt(cmd::SEND);
                root["content"] = m_pTextEdit->toPlainText().toStdString();
                root["time"] = QDateTime::currentDateTime().toString("hh:mm:ss").toStdString();
                Json::StreamWriterBuilder writer;
                std::string outputString1 = Json::writeString(writer, root);
                client->send(outputString1);
                m_pTextEdit->clear();
            //connect(timer, &QTimer::timeout, [this](){
            //    ++executionCount;
            //    if (executionCount >= maxExecutions) {
            //        timer->stop(); // 停止定时器
            //        qDebug() << "Timer stopped after reaching maximum executions.";
            //    }
            //    Json::Value root;
            //    root["cmd"] = cmdToInt(cmd::SEND);
            //    root["content"] = m_pTextEdit->toPlainText().toStdString();
            //    root["time"] = QDateTime::currentDateTime().toString("hh:mm:ss").toStdString();
            //    Json::StreamWriterBuilder writer;
            //    std::string outputString1 = Json::writeString(writer, root);
            //    client->send(outputString1);
            //    std::cout << executionCount << std::endl;
            //});
            //timer->start(50);
            ////m_pTextEdit->clear();
        }
    });

    connect(m_pStartButton, &QPushButton::released, [this]() { 
        
        Json::Value root;//构建该客户端初始化信息，发送给服务器
        root["cmd"] = cmdToInt(cmd::INITCON);
        root["id"] = "Client1";
        Json::StreamWriterBuilder writer;
        std::string outputString = Json::writeString(writer, root);

        std::string url = m_pUrlLineEdit->text().toStdString();
        if (open(url.c_str()))
        {
            client->send(outputString);
            m_pStartButton->setEnabled(false);
            m_pCloseButton->setEnabled(true);
            m_pDisplayTextEdit->append(QString("Client openning to  ..."));
            //设置连接时间，超时释放client
        }
        else
        {
            m_pDisplayTextEdit->append(QString("Client open Failed  !!"));
            close();
        }
           
    });

    connect(m_pCloseButton, &QPushButton::released, [this]() {
        //if(timer!=nullptr) timer->stop();
        close();
        m_pStartButton->setEnabled(true);
        m_pCloseButton->setEnabled(false);
        m_pDisplayTextEdit->append("Client closed");
    });

    connect(m_pSelectImgButton, &QPushButton::released, this, &TWebSocketClient::onSelectImgButtonReleased);
    connect(m_pSendImgButton, &QPushButton::released, this, &TWebSocketClient::onSendImgButtonReleased);
}


bool TWebSocketClient::open(const char* url)
{
    client = new hv::WebSocketClient;
    client->onopen = []() {
        std::cout << "Client Started!" <<std::endl;
    };
    client->onclose = [this]() {
        //收到来自服务器的关闭操作
        //close();
        std::cout << "Client Closed" << std::endl;
    };
    
    client->onmessage = [this](const std::string& msg) {
        std::cout<< "Receive : " << parseContent(msg) << std::endl;
    };
    return client->open(url) == 0;
}

void TWebSocketClient::close()
{
    m_pDisplayTextEdit->clear();
    SAFE_DELETE(client);
}

void TWebSocketClient::initUI()
{
    m_pUrlLabel->resize(50,20);
    m_pUrlLabel->move(50, 20);
    m_pUrlLabel->setText("url:");

    m_pUrlLineEdit->resize(300, 20);
    m_pUrlLineEdit->move(105, 20);
    m_pUrlLineEdit->setText("ws://172.16.191.79:9999/chat");

    m_pStartButton->resize(80, 20);
    m_pStartButton->move(50, 50);
    m_pStartButton->setText("Start");

    m_pCloseButton->resize(80, 20);
    m_pCloseButton->move(150, 50);
    m_pCloseButton->setText("Close");

    m_pTextEdit->resize(400, 200);
    m_pTextEdit->move(10, 80);
    m_pTextEdit->append("测试");

    m_pSendButton->resize(40, 30);
    m_pSendButton->move(420, 150);
    m_pSendButton->setText("Send");

    m_pDisplayTextEdit->resize(240, 200);
    m_pDisplayTextEdit->move(10, 290);

    m_pSelectImgButton->resize(100, 100);
    m_pSelectImgButton->move(260, 290);
    m_pSendImgButton->resize(60, 30);
    m_pSendImgButton->move(370, 300);
    m_pSendImgButton->setText("Upload");
}


TWebSocketClient::~TWebSocketClient()
{
    close();
   // timer->stop();
}

int TWebSocketClient::cmdToInt(cmd command)
{
    return static_cast<int>(command);
}

std::string TWebSocketClient::parseContent(const std::string& msg)
{
    Json::CharReaderBuilder reader;
    Json::Value parsedRoot;
    std::string errs;
    std::istringstream s(msg);
    if (Json::parseFromStream(reader, s, &parsedRoot, &errs))
    {
        return parsedRoot["content"].asString();
    }
}

void TWebSocketClient::onSelectImgButtonReleased()
{
    QString fileName = QFileDialog::getOpenFileName(this, "select iamge", "", "Images (*.png *.gif *.jpg *.bmp *.ico)");
    if (!fileName.isEmpty())
    {
        selectedImagePath = fileName;
        selectedImageName = QFileInfo(fileName).fileName();
        QPixmap pixmap(fileName);
        if (!pixmap.isNull())
        {
            QIcon icon(pixmap);
            m_pSelectImgButton->setIcon(icon);
            m_pSelectImgButton->setIconSize(m_pSelectImgButton->size());
        }
        else
            m_pSelectImgButton->setText("failed to load image");
    }
}

void TWebSocketClient::onSendImgButtonReleased()
{
    if (client == nullptr || !client->isConnected()) {
        m_pDisplayTextEdit->append("Please open first!");
        std::cout << "client has no connection with server" << std::endl;
        return;
    }
    if (!m_pSelectImgButton->icon().isNull()) {
        std::cout << "image is exist" << std::endl;
        Json::Value root;
        root["image"] = imageToString(selectedImagePath);
        root["cmd"] = cmdToInt(cmd::SENDIMG);
        root["image-name"] = selectedImageName.toStdString();
        Json::StreamWriterBuilder writer;
        std::string outputString = Json::writeString(writer, root);
        client->send(outputString);
    }
    else
        std::cout << "image is not exist" << std::endl;
}

std::string TWebSocketClient::imageToString(const QString& filename)
{
    QFile file(filename);
    if (!file.open(QIODevice::ReadOnly)) {
        std::cout << "Failed to open file:" << filename.toStdString() << std::endl;;
        return std::string();
    }
    QByteArray fileData = file.readAll();
    file.close();

    QByteArray base64Data = fileData.toBase64();
    QString base64String = QString::fromUtf8(base64Data);

    return base64String.toStdString();
}